package hust.cs.javacourse.search.index.impl;

import hust.cs.javacourse.search.index.AbstractPosting;
import hust.cs.javacourse.search.index.AbstractPostingList;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.*;

public class PostingList extends AbstractPostingList {
    public PostingList() {
        super();
    }

    /**
     * 添加Posting，不能有重复的
     * @param postings
     */
    @Override
    public void add(AbstractPosting postings) {
        if(this.list.indexOf(postings) == -1)
            this.list.add(postings);
    }

    /**
     * 返回描述PostingList的字符串
     * @return ：PostingList的字符串
     */
    @Override
    public String toString() {
        String info = new String();
        int count = 1;
        int size = this.list.size();
        for(AbstractPosting post: this.list) {
            info += post.toString();
            if(count != size)
                info = info + " -> ";
            count++;
        }
        return info;
    }

    /**
     * 添加Posting列表，不能有重复的
     * @param postings：Posting列表
     */
    @Override
    public void add(List<AbstractPosting> postings) {
        for(int i = 0;i < postings.size();i++) {
            if(!this.list.contains(postings.get(i))) {
                this.list.add(postings.get(i));
            }
        }
    }

    /**
     * 返回指定下标的Posting
     * @param index ：下标
     * @return: Posting
     */
    @Override
    public AbstractPosting get(int index) {
        return this.list.get(index);
    }

    /**
     * 返回指定Posting对象的下标
     * @param posting：指定的Posting对象
     * @return :指定Posting的下标，找不到返回-1
     */
    @Override
    public int indexOf(AbstractPosting posting) {
        Iterator<AbstractPosting> it = this.list.iterator();
        int i = 0;
        while (it.hasNext()) {
            if(it.next().equals(posting)) {
                return i;
            }
            i++;
        }
        return -1;
    }

    /**
     * 返回指定docId对象的Posting的下标
     * @param docId ：文档id
     * @return ：Posting下标，找不到返回-1
     */
    @Override
    public int indexOf(int docId) {
        Iterator<AbstractPosting> it = this.list.iterator();
        int i = 0;
        while (it.hasNext()) {
            if(it.next().getDocId() == docId) {
                return i;
            }
            i++;
        }
        return -1;
    }

    /**
     * 是否包含指定的Posting对象
     * @param posting： 指定的Posting对象
     * @return ：包含返回true，否则返回false
     */
    @Override
    public boolean contains(AbstractPosting posting) {
        return this.list.contains(posting);
    }

    /**
     * 删除指定下标的Posting对象
     * @param index：指定的下标
     */
    @Override
    public void remove(int index) {
        remove(this.list.remove(index));
    }

    /**
     * 删除指定的Posting对象
     * @param posting ：定的Posting对象
     */
    @Override
    public void remove(AbstractPosting posting) {
        Iterator<AbstractPosting> it = this.list.iterator();
        while (it.hasNext()) {
            if(it.next().equals(posting))
                it.remove();
        }
    }

    /**
     * 获取PostingList的大小
     * @return Posting的大小
     */
    @Override
    public int size() {
        return this.list.size();
    }

    /**
     * 清空PostingList
     */
    @Override
    public void clear() {
        this.list.clear();
    }

    /**
     * 判断PostingList是否为空
     * @return
     */
    @Override
    public boolean isEmpty() {
        return this.list.isEmpty();
    }

    /**
     * 对PostingList进行排序
     */
    @Override
    public void sort() {
        Collections.sort(this.list);
    }

    /**
     * 序列化到文件
     * @param out :输出流对象
     */
    @Override
    public void writeObject(ObjectOutputStream out) {
        try{
            out.writeObject(this.list);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 从文件反序列化到成员变量
     * @param in ：输入流对象
     */
    @Override
    public void readObject(ObjectInputStream in) {
        try {
            this.list = (List) (in.readObject());
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}
